import React from "react";
import { connect } from "dva";
import BaseEdit from "./base";
import Page from "./page";
import Itempanel from "./itempanel";
import Toolbar from "./toolbar";
import Detailpannel from "./detailpanel";
import Contextmenu from "./contextmenu";

import styles from "./edit.less";

@connect()
class Index extends BaseEdit {
  constructor(props) {
    super(props);
    this.tableIndex = 0;
    this.editMinHeight = 450;
    this.state = {
      visible: false,
    };
  }

  componentDidMount() {
    super.componentDidMount();
    const { getEditThis, isViewData } = this.props;
    const { editor } = this;
    const flowpage = editor.getCurrentPage();
    if (isViewData) {
      const graph = flowpage.getGraph();
      graph.changeMode("editchart");
    }

    const { isEdit } = this.state;
    flowpage.changeAddEdgeModel({
      shape: "flow-polyline-round",
    });
    // 输入锚点不可以连出边
    flowpage.on("hoveranchor:beforeaddedge", (evt) => {
      if (evt.anchor.type === "input" || isEdit) {
        evt.cancel = true;
      }
    });
    flowpage.on("dragedge:beforeshowanchor", (ev) => {
      const { target, source, targetAnchor, sourceAnchor } = ev;
      // 只允许目标锚点是输入，源锚点是输出，才能连接
      const targetType = targetAnchor.type;
      const sourceType = sourceAnchor.type;
      if (
        !(
          (targetType === "input" || !targetType) &&
          (sourceType === "output" || !sourceType)
        )
      ) {
        ev.cancel = true;
      }
      // 不能连自身
      if (target.id === source.id) {
        ev.cancel = true;
      }
    });
    if (getEditThis) getEditThis(this); // 把this暴露给父组件
  }

  componentDidUpdate(preProps) {
    const { height } = this.props;
    const preHeight =
      preProps.height > this.editMinHeight
        ? preProps.height
        : this.editMinHeight;
    const nowHeight = height > this.editMinHeight ? height : this.editMinHeight;
    if (preHeight !== nowHeight) {
      this.editorForceFit();
    }
  }

  /* 父组件可能要调用的方法-start */

  // 画布适应
  editorForceFit = (fitView) => {
    const { editor } = this;
    const page = editor.getCurrentPage();
    const graph = page.getGraph();
    graph.forceFit(true);
    if (fitView) {
      graph.setFitView(fitView);
    }
  };

  // 设置选中项
  setItemSelected = (itemId, isSelected) => {
    const { editor } = this;
    const page = editor.getCurrentPage();
    page.clearSelected();
    if (itemId) {
      page.setSelected(itemId, isSelected);
    }
  };

  // 获取绘制的内容
  getDrawData = () => {
    const { editor } = this;
    const page = editor.getCurrentPage();
    const data = page.save(); // 保存数据
    const { nodes = [], edges = [], groups = [] } = data;
    return { nodes, edges, groups };
  };

  getNodesData = () => {
    const { dispatch } = this.props;
    const { editor } = this;
    const page = editor.getCurrentPage();
    const data = page.save(); // 保存数据
    const { nodes = [] } = data;
    dispatch({
      type: "FlowChart/set/flowNodesData",
      payload: nodes,
    });
    return nodes;
  };

  // 绘制图
  drawModel = (data) => {
    const { editor } = this;
    const page = editor.getCurrentPage();
    const { nodes = [], edges = [], groups = [] } = data || {};
    page.read({ nodes, edges, groups }); // 反显数据
  };

  // 提供更新节点方法
  updateDrawData = (key, value) => {
    this.getNodesData();
    this.updateGraph(key, value);
  };

  changePageMode = (mode = "default") => {
    const { editor } = this;
    const page = editor.getCurrentPage();
    const graph = page.getGraph();
    graph.changeMode(mode);
  };
  /* 父组件可能要调用的方法-end */

  saveFlow = () => {
    const { onSave } = this.props;
    if (onSave && onSave instanceof Function) {
      const data = this.getDrawData();
      onSave(data);
    }
  };

  render() {
    const {
      height,
      detailpannelContent,
      onBack = () => {},
      className = "",
      containerClassName = "",
      toobarHidden,
      itempanelHidden,
      detailpannelHidden,
      contextmenuHidden,
    } = this.props;
    const { selectedModel } = this.state;
    const newHeight = height > this.editMinHeight ? height : this.editMinHeight;
    return (
      // <div className={cn(styles.editor, "editor")} style={{ height: newHeight }}>
      <div
        className={`editor ${styles.editor} ${className}`}
        style={{ height: newHeight }}
      >
        {!toobarHidden && (
          <Toolbar
            editor={this.editor}
            saveFlow={this.saveFlow}
            className={styles.topbar}
            reBack={onBack}
          />
        )}

        <div
          className={`bottom-container ${styles.flowchart_con} ${containerClassName}`}
        >
          {!itempanelHidden && <Itempanel editor={this.editor} />}
          <Page
            editor={this.editor}
            style={{ height }}
            className={styles.flowchart_page}
          />
          {!detailpannelHidden && (
            <Detailpannel
              editor={this.editor}
              style={{ height }}
              className={styles.detailpannel}
              content={
                detailpannelContent instanceof Function
                  ? detailpannelContent(selectedModel)
                  : detailpannelContent
              }
            />
          )}
        </div>
        {!contextmenuHidden && <Contextmenu editor={this.editor} />}
      </div>
    );
  }
}

export default Index;
